#include "NeoRollerPrivate.h"
#include "NeoRoller.h"
#include <QPropertyAnimation>

NeoRollerPrivate::NeoRollerPrivate(QObject *parent)
    : QObject(parent),
      pCurrentItem(QString()),
      pItems(QStringList()),
      pMaxVisibleItems(5),
      pBackgroundColor(Qt::lightGray),
      pSelectorColor(Qt::blue),
      pTextColor(Qt::black),
      pSelectorTextColor(Qt::white),
      pPreviousIndex(0),
      pCurrentIndex(0),
      pNextIndex(0),
      pItemHeight(0),
      pOffset(0),
      pOffsetAnimation(new QPropertyAnimation(this, "pOffset", this))
{
  pOffsetAnimation->setDuration(300);
  pOffsetAnimation->setEasingCurve(QEasingCurve::Linear);
  pOffsetAnimation->setStartValue(0);
}

NeoRollerPrivate::~NeoRollerPrivate() = default;

void NeoRollerPrivate::updateWidgetGeometry(QSize size)
{
  size.setHeight(size.height() - 2 * NEO_RADIUS_ADJUSTED_VALUE);
  pItemHeight = size.height() / pMaxVisibleItems;
}

void NeoRollerPrivate::updateCurrentItem(int index, bool clockwise)
{
  if (pOffsetAnimation->state() != QPropertyAnimation::Running)
  {
    int gap = clockwise ? (index - pCurrentIndex + pItems.size()) % pItems.size() : (pCurrentIndex - index + pItems.size()) % pItems.size();
    gap = clockwise ? -gap * pItemHeight : gap * pItemHeight;
    pOffsetAnimation->setStartValue(0);
    pOffsetAnimation->setEndValue(gap);
    pOffsetAnimation->start();
    pPreviousIndex = pCurrentIndex;
    pNextIndex = index;
  }
}

void NeoRollerPrivate::drawBackground(QPainter *painter)
{
  NEO_PRIVATE_POINT(NeoRoller)
  painter->save();
  const int borderRadius = 5;
  painter->setPen(pBackgroundColor);
  painter->setBrush(pBackgroundColor);
  painter->drawRoundedRect(q->rect().adjusted(NEO_RADIUS_ADJUSTED_VALUES),
                           borderRadius, borderRadius);
  painter->restore();
}

void NeoRollerPrivate::drawItems(QPainter *painter)
{
  NEO_PRIVATE_POINT(NeoRoller)
  painter->save();
  QRect itemStandardRect = q->rect().adjusted(NEO_RADIUS_ADJUSTED_VALUES);
  itemStandardRect.setHeight(pItemHeight);
  itemStandardRect.moveCenter(q->rect().center());
  for (int i = 0; i < 2 * pMaxVisibleItems - 1; ++i)
  {
    QRect rect = q->rect();
    int yPos = rect.center().y();
    yPos += (i - pMaxVisibleItems + 1) * pItemHeight + pOffset;
    QRect itemRect = QRect(rect.left(), yPos - pItemHeight / 2, rect.width(), pItemHeight).adjusted(NEO_RADIUS_ADJUSTED_VALUES);
    int index = (pPreviousIndex - pMaxVisibleItems + 1 + pItems.size() + i) % pItems.size();
    if (itemStandardRect.intersected(itemRect).height() >= pItemHeight / 2)
    {
      painter->setPen(pSelectorTextColor);
    }
    else
    {
      painter->setPen(pTextColor);
    }
    painter->drawText(itemRect, Qt::AlignCenter, pItems[index]);
  }
  painter->restore();
}

void NeoRollerPrivate::drawSelector(QPainter *painter)
{
  NEO_PRIVATE_POINT(NeoRoller)
  painter->save();
  const int borderRadius = 5;
  painter->setPen(pSelectorColor);
  painter->setBrush(pSelectorColor);
  QRect selectorRect = q->rect().adjusted(NEO_RADIUS_ADJUSTED_VALUES);
  selectorRect.setHeight(selectorRect.height() / pMaxVisibleItems);
  selectorRect.moveCenter(q->rect().center());
  painter->drawRoundedRect(selectorRect, borderRadius, borderRadius);
  painter->restore();
}